/**
 * Date:2021年9月2日 下午9:00:59
 * Copyright (c) 2021, www.bwbroad.com All Rights Reserved
 */

package com.xue.config;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.util.StringUtils;

import com.atomikos.jdbc.AtomikosDataSourceBean;

@Configuration
@EnableJpaRepositories(basePackages = { Ds2RepositoryConfig.PACKAGE }, // 设置dao（repo）所在位置
		entityManagerFactoryRef = "ds2EntityManagerFactory"/* , transactionManagerRef = "transactionManager" */)
public class Ds2RepositoryConfig {
	public static final String PACKAGE = "com.xue.dao.ds2";
	@Autowired
	private JpaProperties jpaProperties;
	@Autowired
	private HibernateProperties hibernateProperties;

	@Bean(name = "ds2Properties")
	@ConfigurationProperties(prefix = "spring.datasource.ds2")
	public DataSourceProperties ds2Properties() {
		return new DataSourceProperties();// 注意是url 而不是jdbc-url
	}

	@Bean(name = "ds2")
	public DataSource ds2() {
//		JdbcDataSource h2XaDataSource = new JdbcDataSource();
//		DataSourceProperties dsp = ds2Properties();
//		System.out.println(dsp.getUrl());
//		h2XaDataSource.setURL(dsp.getUrl());
//		h2XaDataSource.setUser(dsp.getUsername());
//		h2XaDataSource.setPassword(dsp.getPassword());
//		AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
//		atomikosDataSourceBean.setXaDataSource(h2XaDataSource);
//		atomikosDataSourceBean.setUniqueResourceName("ds2");
//		atomikosDataSourceBean.setPoolSize(5);
//		return atomikosDataSourceBean;
		
		
		DataSourceProperties dsp = ds2Properties();
		AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
//		atomikosDataSourceBean.setXaDataSource(h2XaDataSource);
		atomikosDataSourceBean.setUniqueResourceName(dsp.getName());
		atomikosDataSourceBean.setXaDataSourceClassName(dsp.getXa().getDataSourceClassName());
		atomikosDataSourceBean.setPoolSize(5);
		Properties xaProperties=new Properties();
		xaProperties.setProperty("URL", dsp.getUrl());
		xaProperties.setProperty("user", dsp.getUsername());
		xaProperties.setProperty("password", dsp.getPassword());
		atomikosDataSourceBean.setXaProperties(xaProperties);
		return atomikosDataSourceBean;
		
	}

	private JpaVendorAdapter jpaVendorAdapter() {
		HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
		// 设置数据库类型（可使用org.springframework.orm.jpa.vendor包下的Database枚举类）
		jpaVendorAdapter.setDatabase(jpaProperties.getDatabase());
		// 设置打印sql语句
		jpaVendorAdapter.setShowSql(jpaProperties.isShowSql());
		// 设置不生成ddl语句
		jpaVendorAdapter.setGenerateDdl(jpaProperties.isGenerateDdl());
		// 设置hibernate方言
		// jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
		// jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
		return jpaVendorAdapter;
	}

//	@Bean
//	public JdbcTemplate ds2JdbcTemplate(@Qualifier("ds2") DataSource ds) {
//		return new JdbcTemplate(ds);
//	}

	@Bean(name = "ds2EntityManagerFactory")
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

		LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
		entityManager.setJtaDataSource(ds2());
		entityManager.setJpaVendorAdapter(jpaVendorAdapter());
		entityManager.setPackagesToScan(PACKAGE);
		entityManager.setPersistenceUnitName("ds2PersistenceUnit");
		// entityManager.setJpaPropertyMap(properties);
		entityManager.setJpaPropertyMap(hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(),
				new HibernateSettings()));
		return entityManager;

	}

//----------------------------------
	// 初始化ds2的配置
	@Bean(name = "init2")
	@ConfigurationProperties(prefix = "spring.sql.init2")
	public SqlInitializationProperties initConfig() {
		return new SqlInitializationProperties();
	}

	// 执行初始化脚本
	// org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration.class
	// DataSourceScriptDatabaseInitializer
	@Bean("ds2Inint")
	DataSourceScriptDatabaseInitializer dataSourceScriptDatabaseInitializer() {
		SqlInitializationProperties initializationProperties = initConfig();
		DatabaseInitializationSettings settings = createFrom(initializationProperties);
		return new DataSourceScriptDatabaseInitializer(determineDataSource(ds2(),
				initializationProperties.getUsername(), initializationProperties.getPassword()), settings);
	}

	static DatabaseInitializationSettings createFrom(SqlInitializationProperties properties) {
		DatabaseInitializationSettings settings = new DatabaseInitializationSettings();
		settings.setSchemaLocations(
				scriptLocations(properties.getSchemaLocations(), "schema", properties.getPlatform()));
		settings.setDataLocations(scriptLocations(properties.getDataLocations(), "data", properties.getPlatform()));
		settings.setContinueOnError(properties.isContinueOnError());
		settings.setSeparator(properties.getSeparator());
		settings.setEncoding(properties.getEncoding());
		settings.setMode(properties.getMode());
		return settings;
	}

	private static List<String> scriptLocations(List<String> locations, String fallback, String platform) {
		if (locations != null) {
			return locations;
		}
		List<String> fallbackLocations = new ArrayList<>();
		fallbackLocations.add("optional:classpath*:" + fallback + "-" + platform + ".sql");
		fallbackLocations.add("optional:classpath*:" + fallback + ".sql");
		return fallbackLocations;
	}

	private static DataSource determineDataSource(DataSource dataSource, String username, String password) {
		if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
			return DataSourceBuilder.derivedFrom(dataSource).username(username).password(password)
					.type(SimpleDriverDataSource.class).build();
		}
		return dataSource;
	}

}
